home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / dvips / output.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-03-02  |  10.5 KB  |  486 lines

  1. /*
  2.  *   These routines do most of the communicating with the printer.
  3.  *
  4.  *   LINELENGTH tells the maximum line length to send out.
  5.  */
  6. #define LINELENGTH (78)
  7. #include "structures.h" /* The copyright notice in that file is included too! */
  8. #include <ctype.h>
  9. /*
  10.  *   The external routines called here:
  11.  */
  12. extern void error() ;
  13. extern void send_headers() ;
  14. extern FILE *search(), *popen();
  15. /*
  16.  *   These are the external variables used by these routines.
  17.  */
  18. extern integer hh, vv ;
  19. extern fontdesctype *curfnt ;
  20. extern FILE *bitfile;
  21. extern char *oname ;
  22. extern Boolean reverse ;
  23. extern Boolean sendcontrolD, disablecomments, multiplesects ;
  24. extern Boolean usesPSfonts, headers_off ;
  25. extern int numcopies ;
  26. extern int totalpages ;
  27. extern integer pagenum ;
  28. extern Boolean manualfeed ;
  29. extern int quiet ;
  30. extern int actualdpi ;
  31. extern char *iname ;
  32. extern char *paperfmt ;
  33. extern char *getenv() ;
  34. extern char errbuf[] ;
  35. extern shalfword linepos ;
  36. /*
  37.  *   We need a few statics to take care of things.
  38.  */
  39. static integer rhh, rvv ;
  40. static Boolean instring ;
  41. static Boolean lastspecial = 1 ;
  42. static shalfword d ;
  43. static int lastfont ;
  44. static void chrcmd();                   /* just a forward declaration */
  45.  
  46. /*
  47.  *   Some very low level primitives to send output to the printer.
  48.  */
  49.  
  50. /*
  51.  *   This routine copies a file down the pipe.  Search path uses the
  52.  *   header path.
  53.  */
  54. static int infigure ;
  55. void
  56. copyfile(s)
  57.         char *s ;
  58. {
  59.    FILE *f ;
  60.    int c, prevc = '\n' ;
  61.  
  62.    if (infigure) {
  63.       f = search(FIGPATH, s) ;
  64.       (void)sprintf(errbuf, "Couldn't find figure file %s; continuing", s) ;
  65.    } else {
  66.       f = search(HEADERPATH, s) ;
  67.       (void)sprintf(errbuf, "! Couldn't find header file %s", s) ;
  68.    }
  69.    if (f==NULL)
  70.       error(errbuf) ;
  71.    else {
  72.       if (! quiet) {
  73.          (void)fprintf(stderr, "[%s]", s) ;
  74.          (void)fflush(stderr) ;
  75.       }
  76.       if (linepos != 0)
  77.          (void)putc('\n', bitfile) ;
  78.       if (! disablecomments)
  79.          (void)fprintf(bitfile, "%%%%BeginDocument: %s\n", s) ;
  80.       while ((c=getc(f))!=EOF) {
  81.          if (c == '%' && prevc == '\n') { /* skip comments */
  82.             while ((c=getc(f))!=EOF) {
  83.                if (c=='\n')
  84.                   break ;
  85.             }
  86.          } else
  87.             (void)putc(c, bitfile) ;
  88.          prevc = c ;
  89.       }
  90.       if (prevc != '\n')
  91.          (void)putc('\n', bitfile) ;
  92.       linepos = 0 ;
  93.       (void)fclose(f) ;
  94.       if (!disablecomments)
  95.          (void)fprintf(bitfile, "%%%%EndDocument\n") ;
  96.    }
  97. }
  98.  
  99. /*
  100.  *   For included PostScript graphics, we use the above routine, but
  101.  *   with no fatal error message.
  102.  */
  103. void figcopyfile(s)
  104. char *s ;
  105. {
  106.    infigure = 1 ;
  107.    copyfile(s) ;
  108.    infigure = 0 ;
  109. }
  110.  
  111. /*
  112.  *   This next routine writes out a `special' character.  In this case,
  113.  *   we simply put it out, since any special character terminates the
  114.  *   preceding token.
  115.  */
  116. void
  117. specialout(c)
  118.         char c ;
  119. {
  120.    if (linepos >= LINELENGTH) {
  121.       (void)putc('\n', bitfile) ;
  122.       linepos = 0 ;
  123.    }
  124.    (void)putc(c, bitfile) ;
  125.    linepos++ ;
  126.    lastspecial = 1 ;
  127. }
  128.  
  129. void
  130. scout(c)   /* string character out */
  131.         char c ;
  132. {
  133.    if (! instring) {
  134. /*
  135.  *   If we are within 5, we send a newline before starting the string.
  136.  *   This eliminates extraneous backslash-newlines.
  137.  */
  138.       if (linepos + 5 > LINELENGTH) {
  139.          (void)putc('\n', bitfile) ;
  140.          linepos = 0 ;
  141.       }
  142.       (void)putc('(', bitfile) ;
  143.       linepos++ ;
  144.       lastspecial = 1 ;
  145.       instring = 1 ;
  146.    }
  147.    if (c<' ' || c>126 || (c=='%' && linepos + 2 > LINELENGTH)) {
  148.       if (linepos + 5 > LINELENGTH) {
  149.          (void)putc('\\', bitfile) ;
  150.          (void)putc('\n', bitfile) ;
  151.          linepos = 0 ;
  152.       }
  153.       (void)putc('\\', bitfile) ;
  154.       linepos++ ;
  155.       (void)putc('0' + ((c >> 6) & 3), bitfile) ;
  156.       linepos++ ;
  157.       (void)putc('0' + ((c >> 3) & 7), bitfile) ;
  158.       linepos++ ;
  159.       (void)putc('0' + (c & 7), bitfile) ;
  160.       linepos++ ;
  161.    } else if (c == '(' || c == ')' || c == '\\') {
  162.       if (linepos + 3 > LINELENGTH) {
  163.          (void)putc('\\', bitfile) ;
  164.          (void)putc('\n', bitfile) ;
  165.          linepos = 0 ;
  166.       }
  167.       (void)putc('\\', bitfile) ;
  168.       linepos++ ;
  169.       (void)putc(c, bitfile) ;
  170.       linepos++ ;
  171.    } else {
  172.       if (linepos + 2 > LINELENGTH) {
  173.          (void)putc('\\', bitfile) ;
  174.          (void)putc('\n', bitfile) ;
  175.          linepos = 0 ;
  176.       }
  177.       (void)putc(c, bitfile) ;
  178.       linepos++ ;
  179.    }
  180. }
  181.  
  182. void
  183. stringend()
  184. {
  185.    instring = 0 ;
  186.    specialout(')') ;
  187. }
  188.  
  189. void
  190. cmdout(s)
  191.         char *s ;
  192. {
  193.    int l ;
  194.  
  195.    /* hack added by dorab */
  196.    if (instring) {
  197.         stringend();
  198.         chrcmd('p');
  199.    }
  200.    l = strlen(s) ;
  201.    if (linepos + l >= LINELENGTH) {
  202.       (void)putc('\n', bitfile) ;
  203.       linepos = 0 ;
  204.       lastspecial = 1 ;
  205.    }
  206.    if (! lastspecial) {
  207.       (void)putc(' ', bitfile) ;
  208.       linepos++ ;
  209.    }
  210.    while (*s != 0) {
  211.       (void)putc(*s++, bitfile) ;
  212.    }
  213.    linepos += l ;
  214.    lastspecial = 0 ;
  215. }
  216.  
  217. static void
  218. chrcmd(c)
  219.         char c ;
  220. {
  221.    if (linepos + 2 > LINELENGTH) {
  222.       (void)putc('\n', bitfile) ;
  223.       linepos = 0 ;
  224.       lastspecial = 1 ;
  225.    }
  226.    if (! lastspecial) {
  227.       (void)putc(' ', bitfile) ;
  228.       linepos++ ;
  229.    }
  230.    (void)putc(c, bitfile) ;
  231.    linepos++ ;
  232.    lastspecial = 0 ;
  233. }
  234.  
  235. void
  236. numout(n)
  237.         integer n ;
  238. {
  239.    char buf[10] ;
  240.  
  241.    (void)sprintf(buf, "%ld", n) ;
  242.    cmdout(buf) ;
  243. }
  244.  
  245. void mhexout(p, len)
  246. register unsigned char *p ;
  247. register long len ;
  248. {
  249.    register char *hexchar = "0123456789ABCDEF" ;
  250.    register int linep ;
  251.    register int n ;
  252.  
  253.    linep = linepos ;
  254.    while (len > 0) {
  255.       if (linep > LINELENGTH - 2) {
  256.          (void)putc('\n', bitfile) ;
  257.          linep = 0 ;
  258.       }
  259.       n = *p++ ;
  260.       (void)putc(hexchar[n >> 4], bitfile) ;
  261.       (void)putc(hexchar[n & 15], bitfile) ;
  262.       linep += 2 ;
  263.       len-- ;
  264.    }
  265.    linepos = linep ;
  266. }
  267.  
  268. void
  269. fontout(n)
  270.         int n ;
  271. {
  272.    char buf[6] ;
  273.  
  274.    if (instring) {
  275.       stringend() ;
  276.       chrcmd('p') ;
  277.    }
  278.    if (n < 27)
  279.       (void)sprintf(buf, "f%c", 'a'+n-1) ;
  280.    else
  281.       (void)sprintf(buf, "f%d", n-27) ;
  282.    cmdout(buf) ;
  283. }
  284.  
  285. void
  286. hvpos()
  287. {
  288.    if (rvv != vv) {
  289.       if (instring) {
  290.          stringend() ;
  291.          numout(hh) ;
  292.          numout(vv) ;
  293.          chrcmd('y') ;
  294.       } else if (rhh != hh) {
  295.          numout(hh) ;
  296.          numout(vv) ;
  297.          chrcmd('a') ;
  298.       } else { /* hard to get this case, but it's there when you need it! */
  299.          numout(vv - rvv) ;
  300.          chrcmd('x') ;
  301.       }
  302.       rvv = vv ;
  303.    } else if (rhh != hh) {
  304.       if (instring) {
  305.          stringend() ;
  306.          if (hh - rhh < 5 && rhh - hh < 5) {
  307.             chrcmd('p' + hh - rhh) ;
  308.          } else if (hh - rhh < d + 5 && rhh - hh < 5 - d) {
  309.             chrcmd('g' + hh - rhh - d) ;
  310.             d = hh - rhh ;
  311.          } else {
  312.             numout(hh - rhh) ;
  313.             chrcmd('b') ;
  314.             d = hh - rhh ;
  315.          }
  316.       } else {
  317.          numout(hh - rhh) ;
  318.          chrcmd('w') ;
  319.       }
  320.    }
  321.    rhh = hh ;
  322. }
  323.  
  324. /*
  325.  *   initprinter opens the bitfile and writes the initialization sequence
  326.  *   to it.
  327.  */
  328. void newline()
  329. {
  330.    if (linepos != 0) {
  331.       (void)fprintf(bitfile, "\n") ;
  332.       linepos = 0 ;
  333.    }
  334. }
  335. void
  336. initprinter()
  337. {
  338.    if (*oname != 0) {
  339. /*
  340.  *   We check to see if the first character is a exclamation
  341.  *   point, and popen if so.
  342.  */
  343.       if (*oname == '!' || *oname == '|') {
  344.          if ((bitfile=popen(oname+1, "w"))==NULL)
  345.             error("! couldn't open output pipe") ;
  346.       } else {
  347.          if ((bitfile=fopen(oname,"w"))==NULL)
  348.             error("! couldn't open PostScript file") ;
  349.       }
  350.    } else {
  351.       bitfile = stdout ;
  352.    }
  353.    if (disablecomments)
  354.       (void)fprintf(bitfile,
  355.              "%%!PS (but not EPSF; comments have been disabled)\n") ;
  356.    else {
  357.       if (multiplesects)
  358.          (void)fprintf(bitfile,
  359.              "%%!PS (but not EPSF because of memory limits)\n") ;
  360.       else  (void)fprintf(bitfile, "%%!PS-Adobe-2.0\n") ;
  361.       (void)fprintf(bitfile, "%%%%Creator: dvips by Radical Eye Software\n") ;
  362.       if (*iname)
  363.          (void)fprintf(bitfile, "%%%%Title: %s\n", iname) ;
  364.       (void)fprintf(bitfile, "%%%%Pages: %d %d\n", totalpages, 1 - 2*reverse) ;
  365.       if (strcmp(paperfmt,"letter")==0)
  366.          (void)fprintf(bitfile, "%%%%BoundingBox: 0 0 612 792\n") ; /*8.5x11*/
  367.       else if (strcmp(paperfmt,"landscape")==0)
  368.          (void)fprintf(bitfile, "%%%%BoundingBox: 0 0 792 612\n") ;
  369.       else if (strcmp(paperfmt,"a4")==0)
  370.          (void)fprintf(bitfile, "%%%%BoundingBox: 0 0 612 842\n") ;
  371.       else (void)fprintf(bitfile, "%%%%BoundingBox: 0 0 612 1008\n"); /*8.5x14*/
  372.       (void)fprintf(bitfile, "%%%%EndComments\n") ;
  373.    }
  374.    if (! headers_off)
  375.       send_headers() ;
  376. }
  377.  
  378. static int endprologsent ;
  379. setup() {
  380.    cmdout("end") ;
  381.    newline() ;
  382.    if (endprologsent == 0 && !disablecomments) {
  383. #if 0
  384.       (void)fprintf(bitfile, "%%%%EndProlog\n") ;
  385. #endif
  386.       (void)fprintf(bitfile, "%%%%BeginSetup\n") ;
  387.       (void)fprintf(bitfile, "%%%%Feature: *Resolution %d\n", DPI) ;
  388.    }
  389.    cmdout("TeXDict") ;
  390.    cmdout("begin") ;
  391.    {  char pft[100] ;
  392.       strcpy(pft, "@") ;
  393.       strcat(pft, paperfmt) ;
  394.       cmdout(pft) ;
  395.    }
  396.    if (manualfeed) cmdout("@manualfeed") ;
  397.    if (numcopies != 1) {
  398.       numout((integer)numcopies) ;
  399.       cmdout("@copies") ;
  400.    }
  401.    if (endprologsent == 0 && !disablecomments) {
  402.       newline() ;
  403.       endprologsent = 1 ;
  404.       (void)fprintf(bitfile, "%%%%EndSetup\n") ;
  405.    }
  406.  
  407. }
  408. /*
  409.  *   cleanprinter is the antithesis of the above routine.
  410.  */
  411. void
  412. cleanprinter()
  413. {
  414.    (void)fprintf(bitfile, "\n") ;
  415.    if (!disablecomments)
  416.       (void)fprintf(bitfile, "%%%%EOF\n") ;
  417.    if (sendcontrolD)
  418.       (void)putc(4, bitfile) ;
  419.    (void)fclose(bitfile) ;
  420.    bitfile = NULL ;
  421. }
  422.  
  423. /*
  424.  *   pageinit initializes the output variables.
  425.  */
  426. static int thispage = 0 ;
  427. void
  428. pageinit()
  429. {
  430.    rhh = rvv = -3141592653 ;
  431.    newline() ;
  432.    if (!disablecomments)
  433.       (void)fprintf(bitfile, "%%%%Page: %ld %d\n", pagenum, ++thispage) ;
  434.    linepos = 0 ;
  435.    cmdout("bop") ;
  436.    lastfont = -1 ;
  437.    d = 0 ;
  438. }
  439.  
  440. /*
  441.  *   This routine ends a page.
  442.  */
  443. void
  444. pageend()
  445. {
  446.    if (instring) {
  447.       stringend() ;
  448.       chrcmd('p') ;
  449.    }
  450.    cmdout("eop") ;
  451. }
  452.  
  453. /*
  454.  *   drawrule draws a rule at the specified position.
  455.  */
  456. void
  457. drawrule(rw, rh)
  458.         shalfword rw, rh ;
  459. {
  460.    hvpos() ;
  461.    if (instring) {
  462.       stringend() ;
  463.       chrcmd('p') ;
  464.    }
  465.    numout((integer)rw) ;
  466.    numout((integer)rh) ;
  467.    chrcmd('v') ;
  468. }
  469.  
  470. /*
  471.  *   drawchar draws a character at the specified position.
  472.  */
  473. void
  474. drawchar(c, cc)
  475.         chardesctype *c ;
  476.         int cc ;
  477. {
  478.    hvpos() ;
  479.    if (lastfont != curfnt->psname) {
  480.       fontout((int)curfnt->psname) ;
  481.       lastfont = curfnt->psname ;
  482.    }
  483.    scout(cc) ;
  484.    rhh = hh + c->pixelwidth ; /* rvv = rv */
  485. }
  486.